package cn.com.miao.lynx.common.base.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * TreeModel
 *
 * @title: TreeModel
 * @description:
 * @author: dengmiao
 * @create: 2019-12-23 16:26
 **/
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@MappedSuperclass
public abstract class TreeModel<E, ID extends Serializable> extends BaseModel<ID> {

    /**
     * 父id
     */
    private ID parentId;

    /**
     * 父id集合 逗号分隔
     */
    private String parentIds;

    /**
     * 树icon
     */
    private String icon;

    /**
     * 直属子节点
     */
    @Transient
    private List<E> children = new ArrayList<>();

    /**
     * 构造树型结构
     * @param meta  元数组
     * @param <E>   TreeModel类型
     * @param <ID>  id类型
     * @return      填充子节点后的集合
     */
    public static <E extends TreeModel, ID extends Serializable> List<E> toChildren(List<E> meta) {
        Map<ID, E> mapping = meta.stream().collect(Collectors.toMap(item -> (ID) item.getId(), Function.identity()));
        Iterator<E> iterator = meta.iterator();
        while (iterator.hasNext()) {
            E item = iterator.next();
            E parent = mapping.get(item.getParentId());
            if (parent != null) {
                parent.getChildren().add(item);
                iterator.remove();
            }

        }
        return meta;
    }
}
